//
//  ListSortDescriptor.m
//  Task Views
//
//  Created by Chris Karr on 3/30/09.
//  Copyright 2009 Audacious Software. All rights reserved.
//

#import "ListSortDescriptor.h"


@implementation ListSortDescriptor

- (NSComparisonResult) compareObject:(id) object1 toObject:(id) object2
{
	id valueOne = [object1 valueForKey:[self key]];
	id valueTwo = [object2 valueForKey:[self key]];
 
	NSComparisonResult result = -999; // placeholder value
	
	if (valueOne == nil)
	{
		if (valueTwo == nil)
			result = NSOrderedSame;
		else
			result = NSOrderedAscending;
	}
	else if (valueTwo == nil)
		result = NSOrderedDescending;
	else if ([valueOne isKindOfClass:[NSDate class]] && [valueTwo isKindOfClass:[NSDate class]])
	{
		result = [[valueOne dateWithCalendarFormat:nil timeZone:nil] 
				  compare:[valueTwo dateWithCalendarFormat:nil timeZone:nil]];
	}
	else if ([valueOne isMemberOfClass:[valueTwo class]])
	{
		if ([valueOne respondsToSelector:@selector(compare:)])
			result = [valueOne compare:valueTwo];
	}
	else if ([valueOne isKindOfClass:[NSNumber class]])
		result = NSOrderedAscending;
	else if ([valueOne isKindOfClass:[NSDate class]])
	{
		if ([valueTwo isKindOfClass:[NSNumber class]])
			result = NSOrderedDescending;
		else
			result = NSOrderedAscending;
	}

	if (result == -999)
		result = [[valueOne description] compare:[valueTwo description]];
	
	if (![self ascending])
	{
		if (result == NSOrderedAscending)
			return NSOrderedDescending;
		else if (result == NSOrderedDescending)
			return NSOrderedAscending;
	}
	
	return result;
}

/*
 * Thanks to Brian Webster for pointing out that the following is necessary:
 *  http://www.fatcatsoftware.com/blog/2007/subclassing-nssortdescriptor-for-fun-and-profit
 */

- (id)copyWithZone:(NSZone*)zone
{
	return [[ListSortDescriptor alloc] initWithKey:[self key] ascending:[self ascending] selector:[self selector]];
}

- (id)reversedSortDescriptor
{
	return [[[ListSortDescriptor alloc] initWithKey:[self key] ascending:![self ascending] selector:[self selector]] autorelease];
}

@end
